function BuildNucleus(div) {
    this.div = div;
    this.atom = new Atom(div.attr("atom"));
    this.attempts = 0;
    this.complete = false;
}

BuildNucleus.prototype = {
    start:function () {
        var a = this.atom;
        var d = this.div;
        var isotope = a.element.name + "-" + a.nucleons;
        d.html("<p>" + isotope + " has an atomic number of " + a.protons +
            " and an atomic mass of " + a.nucleons + ". Build its nucleus by dragging" +
            " and dropping the nucleons on the sides into the target in the center.</p>" +
            "<div class='build_target'><div class='name'>" + isotope + "</div>" +
            "<div class='number'>Atomic number = " + a.protons + "</div>" +
            "<div class='mass'>Atomic mass = " + a.nucleons + "</div>" +
            "<div class='drop'></div></div>");
        var bt = d.find(".build_target");
        var drop = bt.find(".drop");
        drop.x = util.getLeft(bt) + util.getLeft(drop) + 0.5 * drop.width();
        drop.y = util.getTop(bt) + util.getTop(drop) + 0.5 * drop.height();
        this.drop = drop;

        for (var j = 0; j < (a.nucleons < 6 ? 8 : 12); j++) {
            var left = (j % 2 == 0 ? 120 : 540) + (j % 4 < 2 ? 0 : 80);
            var top = (a.nucleons < 6 ? 120 : 80) + Math.floor(j / 4) * 80;
            d.append("<canvas class='" + (j % 2 == 0 ? "proton" : "neutron") + "' " +
                "style='position:absolute;left:" + left + "px;top:" + top + "px;'" +
                "width='40px' height='40px' left='" + left + "' top='" + top + "'></div>")
        }
        d.append("<div class='check_answer'><button>Check<br />Answer</button></div>");
        var btn = d.find(".check_answer button");
        btn.click(this,function (event) {
            event.data.checkAnswer();
        }).button();
        this.addEventListeners();
        drawNucleons(d);
    },

    addEventListeners:function () {
        var d = this.div;
        $.each(d.find("canvas.proton, canvas.neutron"), function (i, c) {
            mouse.addStart($(c));
        });
        var body = $("body");
        mouse.addMove(body);
        d.bind("mouseup touchend", this, function (event) {
            if (!mouse.target) {
                return;
            }
            event.data.positionNucleons(mouse.target.parent());
            mouse.down = false;
            mouse.target = false;
        });
        body.bind("mouseup touchend", this, function (event) {
            $("body").enableSelection();
            if (mouse.target) {
                var t = mouse.target;
                t.animate({ left:t.attr("left"), top:t.attr("top") });
                mouse.down = false;
                mouse.target = false;
            }
        });
    },

    positionNucleons:function () {
        var bn = this;
        var d = this.div;
        var drop = this.drop;
        d.find(".check_answer button").css({ opacity:1 });
        d.find(".check_answer").css({ background:"none" });

        var nucleons = d.find("canvas.proton, canvas.neutron");
        var valid = nucleons.filter(function (i, c) {
            return bn.getDistanceFromDrop($(c)) < 60;
        });
        $.each(nucleons, function (i, c) {
            if ($.inArray(c, valid) > -1) {
                return;
            }
            var n = $(c);
            n.animate({ left:n.attr("left"), top:n.attr("top") });
        });
        if (valid.length > 0) {
            var nc = am2nc[valid.length];
            for (var i = 0; i < valid.length; i++) {
                var n = $(valid[i]);
                var scale = 140;
                var left = drop.x - 0.5 * n.width() + nc[i * 2] * scale;
                var top = drop.y - 0.5 * n.height() + nc[i * 2 + 1] * scale;
                n.animate({ left:left, top:top });
            }
        }
    },

    getDistanceFromDrop:function (nucleon) {
        nucleon.x = nucleon.position().left + 0.5 * nucleon.width();
        nucleon.y = nucleon.position().top + 0.5 * nucleon.height();
        var dx = nucleon.x - this.drop.x;
        var dy = nucleon.y - this.drop.y;
        return Math.pow(dx * dx + dy * dy, 0.5);
    },

    checkAnswer:function () {
        var a = this.atom;
        var d = this.div;
        var bn = this;
        var protons = 0;
        var neutrons = 0;
        $.each(d.find("canvas.proton, canvas.neutron"), function (i, c) {
            var nucleon = $(c);
            if (bn.getDistanceFromDrop(nucleon) < 80) {
                if (nucleon.hasClass("proton")) {
                    protons++;
                }
                else if (nucleon.hasClass("neutron")) {
                    neutrons++;
                }
            }
        });
        if (protons > 0 || neutrons > 0) {
            this.attempts++;
        }
        var correct = protons == a.protons && neutrons == a.neutrons;
        var background = "url('/assets/" + (correct ? "apply" : "cancel") + ".png') center center no-repeat";
        d.find(".check_answer button").css({ opacity:0 });
        d.find(".check_answer").css({ background:background });
        this.complete = correct;
        $("body").trigger($.Event("update_score"));
    }
};